﻿using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using __ts.Core.Plugin;
using __ts.Core.Utilities;
using System.Threading;

namespace CCU
{
    public partial class MainForm : Form
    {
        private NotifyIcon tray = null;
        private bool boolForceExit = false;

        /// <summary>
        /// 
        /// </summary>
        private void StartNetTcpPortSharingService()
        {
            if (Util.IsRuningWithAdministrator())
            {
                Utils.RunCmd("sc config NetTcpPortSharing start= auto obj= LocalSystem");
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public MainForm()
        {
            StartNetTcpPortSharingService();
            InitializeComponent();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ModuleManage_Load(object sender, EventArgs e)
        {
            MinimizeToTray();
            tray.ShowBalloonTip(1000*10, "CCU Tips", "Waiting server to push configs.", ToolTipIcon.Info);

            this.backgroundWorker1.RunWorkerAsync();
        }
        /// <summary>
        /// 
        /// </summary>
        private void Init()
        {
            dataGridView1.AutoGenerateColumns = false;
            dataGridView1.RowHeadersWidth = 30;
            dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            dataGridView1.ColumnHeadersDefaultCellStyle.Padding = new Padding(1, 4, 1, 4);
            dataGridView1.Columns[1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            dataGridView1.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            dataGridView1.Columns[3].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            dataGridView1.Columns[4].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
            dataGridView1.Columns[6].DefaultCellStyle.Padding = new Padding(4, 1, 4, 1);
            dataGridView1.DataSource = GetDataTable();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private static DataTable GetDataTable()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("Index", typeof(int)));
            dt.Columns.Add(new DataColumn("ModuleName", typeof(String)));
            dt.Columns.Add(new DataColumn("ModuleKey", typeof(String)));
            dt.Columns.Add(new DataColumn("Port", typeof(String)));
            dt.Columns.Add(new DataColumn("State", typeof(String)));
            dt.Columns.Add(new DataColumn("HostDate", typeof(String)));
            dt.Columns.Add(new DataColumn("Description", typeof(String)));

            System.Collections.IDictionaryEnumerator enumerator = PluginManager.GetInstance.Plugins.GetEnumerator();
            int i = 0;
            while (enumerator.MoveNext())
            {
                PluginDomain ad = (PluginDomain)enumerator.Value;
                IPlugin p = null;
                if (ad != null && (p = ad.GetPlugin()) != null)
                {
                    DataRow dr = dt.NewRow();
                    dr["Index"] = i++;
                    dr["ModuleName"] = p.Name;
                    dr["ModuleKey"] = p.Key;
                    dr["Port"] = String.Join(",", Array.ConvertAll<int, String>(p.Ports.ToArray(), Convert.ToString));
                    dr["State"] = p.State.ToString();
                    dr["HostDate"] = p.HostDate;
                    dr["Description"] = p.Description;

                    dt.Rows.Add(dr);
                }
            }
            return dt;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex > -1 && e.ColumnIndex == -1)
            {
                e.PaintBackground(e.CellBounds, false);
                //e.Graphics.FillEllipse(Brushes.Red, e.CellBounds);
                e.Graphics.DrawString((e.RowIndex + 1).ToString(), this.Font, Brushes.Black, new PointF(e.CellBounds.X + 8, e.CellBounds.Y + 8));
                e.Handled = true;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            int iCol = e.ColumnIndex;
            int iRow = e.RowIndex;

            if (iRow > -1 && iCol > -1)
            {
                DataGridViewRow dgr = dataGridView1.Rows[iRow];
                DataRowView dv = dgr.DataBoundItem as DataRowView;
                string moduleKey = dv.Row["ModuleKey"].ToString();

                PluginDomain ad = PluginManager.GetInstance.GetPluginDomain(moduleKey);
                IPlugin p = ad.GetPlugin();

                dgr.Cells[1].ToolTipText = p.Description;

                if (iCol == 5)
                {
                    string message = "Are you sure to Stop \"" + p.Name + "\"?";
                    if (MessageBox.Show(message, "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                    {
                        if (dgr.Cells[iCol].Value.ToString() == "Opened")
                        {
                            dgr.Cells[4].Value = "Closed";
                            p.Unhost();
                        }
                        else
                        {
                            dgr.Cells[4].Value = "Opened";
                            p.Host();
                            p.HostDate = DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss");
                        }
                    }
                }
                else if (iCol == 6)
                {
                    string message = "Are you sure to Uninstall \"" + p.Name + "\"?";
                    if (MessageBox.Show(message, "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                    {
                        dataGridView1.Rows.RemoveAt(iRow);
                        ad.Unload();
                    }
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRefresh_Click(object sender, EventArgs e)
        {
            Init();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MinimizeToTray(object sender, EventArgs e)
        {
            MinimizeToTray();
        }
        /// <summary>
        /// 
        /// </summary>
        private void MinimizeToTray()
        {
            // Tray icon already created
            if (tray != null)
            {
                tray.Visible = true;
                this.Hide();
                return;
            }

            // Setup tray icon
            tray = new NotifyIcon();
            tray.Icon = this.Icon;
            //Version v = new Version(Application.ProductVersion);
            tray.Text = "CCU 2.0";// + v.Major + "." + v.Minor;

            // Create menu
            tray.ContextMenuStrip = mnContextTray;

            // Double click opens Todomoo
            //tray.DoubleClick += ShowMainForm;

            // Hide form and show tray icon
            tray.Visible = true;
            this.Hide();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ShowMainForm(object sender, EventArgs e)
        {
            ShowMainForm();
        }
        /// <summary>
        /// 
        /// </summary>
        private void ShowMainForm()
        {
            this.Show();
            if (tray != null)
            {
                tray.Visible = false;
            }
            this.Init();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Exit(object sender, EventArgs e)
        {
            boolForceExit = true;
            tray.Visible = false;
            this.Close();
            boolForceExit = false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void Exit(object sender, FormClosingEventArgs e)
        {
            if (!boolForceExit)
            {
                e.Cancel = true;
                MinimizeToTray();
                return;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            mnContextTray.Items[0].Enabled = false;
            mnContextTray.Items[2].Enabled = false;
            if (!File.Exists("config.xml"))
                mnContextTray.Items[3].Enabled = false;
            
            // 待完成：等待推送配置
            // ========================================
            // 监听端口，等待配置服务器发送配置过来，然后生成配置文件，继续往下启动程序。
            // 
            // 
            // 
            // 
            // 
            // 
            // 
            // 


            Thread.Sleep(1000 * 5);


            tray.ShowBalloonTip(3000, "CCU Tips", "CCU configs was successfully generated. \nPlease wait for loading plugins.", ToolTipIcon.Info);

            // 加载指定目录下的所有模块
            PluginManager m = PluginManager.GetInstance;
            m.init();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            mnContextTray.Items[0].Enabled = true;
            mnContextTray.Items[2].Enabled = true;
            mnContextTray.Items[3].Enabled = true;
            this.Icon = this.icon2;
            tray.Icon = this.Icon;

            tray.ShowBalloonTip(3000, "CCU Tips", "All plugins loaded successful.", ToolTipIcon.Info);
            Init();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void shToolStripMenuItem_Click(object sender, EventArgs e)
        {
            GuardianForm.Current.Show();
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ToUpdate(object sender, System.EventArgs e)
        {
            const string updateModulePath = "CCU.Update.exe";

            if (File.Exists(updateModulePath))
                Process.Start(updateModulePath);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mnTraySettings_Click(object sender, EventArgs e)
        {
            ConfigsManageForm.Current.Show();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnHostAll_Click(object sender, EventArgs e)
        {
            System.Collections.IDictionaryEnumerator enumerator = PluginManager.GetInstance.Plugins.GetEnumerator();
            while (enumerator.MoveNext())
            {
                PluginDomain ad = (PluginDomain)enumerator.Value;
                IPlugin p = null;
                if (ad != null && (p = ad.GetPlugin()) != null)
                {
                    if (p.State != System.ServiceModel.CommunicationState.Opened)
                        p.Host();
                }
            }
            Init();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStopHostAll_Click(object sender, EventArgs e)
        {
            System.Collections.IDictionaryEnumerator enumerator = PluginManager.GetInstance.Plugins.GetEnumerator();
            while (enumerator.MoveNext())
            {
                PluginDomain ad = (PluginDomain)enumerator.Value;
                IPlugin p = null;
                if (ad != null && (p = ad.GetPlugin()) != null)
                {
                    if (p.State != System.ServiceModel.CommunicationState.Closed)
                        p.Unhost();
                }
            }
            Init();
        }

        private void packageBuilderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            const string packageBuilderPath = "CCU.PackageBuilder.exe";

            if (File.Exists(packageBuilderPath))
                Process.Start(packageBuilderPath);
        }
    }
}
